#include <stdint.h>
#include "g711.h"
static uint8_t *GetNextHisiHeader(uint8_t *pBufPtr, uint32_t u32Len)
{
    uint8_t *pEndPtr = pBufPtr + u32Len;
    while (pBufPtr != pEndPtr) {
        if (0x00 == pBufPtr[0] && 0x01 == pBufPtr[1]) {
            return pBufPtr;
        } else {
            pBufPtr++;
        }
    }
    return NULL;
}

static uint32_t getG711FrameLen(uint8_t *hisiHeader)
{
    uint32_t framelen = 0;
    if (!hisiHeader) {
        return 0;
    }

    framelen = hisiHeader[2] * 2;  // g711a frame len unit is s16
    return framelen;
}

int32_t G711_Open(G711_Handle_S *pstHandle, const char *pszFilePath)
{
    return Stream_Open(&pstHandle->stStream, pszFilePath, 1024);
}

int32_t G711_ReadFrame(G711_Handle_S *pstHandle, uint8_t **ppFrame, uint32_t *pu32FrameLen)
{
    fseek(pstHandle->stStream.pFile, pstHandle->stStream.u32FileReadOffset, SEEK_SET);
    memset(pstHandle->stStream.pu8BufHeader, 0x00, pstHandle->stStream.u32BufLen);
    uint32_t readLen = fread(pstHandle->stStream.pu8BufHeader, 1, pstHandle->stStream.u32BufLen,
                             pstHandle->stStream.pFile);
    if (readLen <= 0) {
        printf("G711A_ReadFrame read file failed\n");
        pstHandle->stStream.u32FileReadOffset = 0;
        return -1;
    }

    pstHandle->stStream.u32AvailReadLen = readLen;
    uint8_t *pBufPtr = pstHandle->stStream.pu8BufHeader;
    uint8_t *pEndPtr = pBufPtr + pstHandle->stStream.u32AvailReadLen;
    uint8_t *hisiHeader = GetNextHisiHeader(pBufPtr, pstHandle->stStream.u32AvailReadLen);
    if (hisiHeader) {
        *pu32FrameLen = getG711FrameLen(hisiHeader);
        *ppFrame = hisiHeader + 4;  // tick out hisi header
        pstHandle->stStream.u32FileReadOffset += (*pu32FrameLen + 4);
        return 0;
    } else {
        perror("g711a read EOF");
        pstHandle->stStream.u32FileReadOffset = 0;
        return -1;
    }
}

int32_t G711_Close(G711_Handle_S *pstHandle)
{
    return Stream_Close(&pstHandle->stStream);
}

int32_t G711_Reset(G711_Handle_S *pstHandle)
{
    return Stream_Reset(&pstHandle->stStream);
}
